﻿

#region File Description

#endregion


#region Using Statements

// System References
using System;
using System.Collections.Generic;
using System.Linq;

// XNA References
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

// Freeform References
using Freeform.Framework;
using Freeform.Framework.Graphics;
using Freeform.Framework.Utility;
using Freeform.Framework.Input;
using Freeform.Framework.Menu;
using System.IO;

// Internal References

#endregion


namespace CardGame.Adventure
{
    public class AdventureWorld : World
    {

        #region Members

        public Entity Title { get; set; }

        public MenuItem_Text CardWorld, Exit;
        public List<MenuItem_Text> EditorLabels = new List<MenuItem_Text>();
        private Int32 Increment;

        public TileClass TileClass;
        public Viewport2D View;

        private Single VerticalPosition = 32f;
        private Single VerticalOffset = 9f;

        private Boolean EnterPressed = false;
        private Boolean ClickPressed = false;
        private Boolean LoadWorldDialog = false;

        private Vector2 CameraAmount = Vector2.One;
        private KeyBinding Up;
        private KeyBinding Down;
        private KeyBinding Left;
        private KeyBinding Right;
        private KeyBinding Enter;
        private KeyBinding Load;

        #endregion


        #region Initialisation

        public AdventureWorld()
        {
            // Make background invisible.
            BackgroundColour = new Color(Vector4.Zero);

            // KeyBindings
            Up = new KeyBinding("Up", Keys.Up);
            Down = new KeyBinding("Down", Keys.Down);
            Left = new KeyBinding("Left", Keys.Left);
            Right = new KeyBinding("Right", Keys.Right);
            Enter = new KeyBinding("Enter", Keys.Enter);
            Load = new KeyBinding("Load", Keys.L);

            // Create Map
            TileClass = new TileClass(this);

            TileClass.SpatialProperties.Position = new Vector2(50f, -15);
            TileClass.SpatialProperties.Size = new Vector2(1, 1);


            // Create title.
            Title = new Entity(this);
            Title.SpatialProperties.Position = new Vector2(20f, 2);
            Title.SpatialProperties.Size = new Vector2(30, 10);
            Title.Actor = new Actor_Text2D(Title, "Adventure World", Game.Content.Load<SpriteFont>("Font/Basic"));
            (Title.Actor as Actor_Text2D).UseNaturalFontSize = true;
            (Title.Actor as Actor_Text2D).NaturalFontScaling = Vector2.One / 4f;
            Title.Actor.Depth = 0.70f;
            Title.Actor.ColourOverlay = Color.White;


            // Create buttons.
            MakeItem(ref CardWorld, "TODO");
            MakeItem(ref Exit, "Exit");

            CardWorld.SpatialProperties.Position = new Vector2(10f, 8);
            CardWorld.Actor.Depth = 0.7f;
            CardWorld.Actor.ColourOverlay = Color.Gray;
            CardWorld.IsEnabled = false;
            Exit.SpatialProperties.Position = new Vector2(10f, 12);
            Exit.Actor.Depth = 0.7f;
 
            // Setup key bindings.
            Up.Pressed += delegate(Object Item, EventArgs Args){ View.Camera.SpatialProperties.Position -= new Vector2(0f, CameraAmount.Y);};
            Down.Pressed += delegate(Object Item, EventArgs Args) { View.Camera.SpatialProperties.Position += new Vector2(0f, CameraAmount.Y); };
            Left.Pressed += delegate(Object Item, EventArgs Args) { View.Camera.SpatialProperties.Position -= new Vector2(CameraAmount.X, 0f); };
            Right.Pressed += delegate(Object Item, EventArgs Args) { View.Camera.SpatialProperties.Position += new Vector2(CameraAmount.X, 0f); };
            Enter.Pressed += delegate(Object Item, EventArgs Args) { EnterPressed = true; };
            Load.Pressed += delegate(Object Item, EventArgs Args)
            {
                SetUpLoadScreen(); View.Camera.SpatialProperties.Position = Vector2.Zero;
            };


            // Setup button clicked events.
            CardWorld.ItemClicked += delegate(Object Item, EventArgs Args)
            {};
            Exit.ItemClicked += delegate(Object Item, EventArgs Args) { Game.Exit(); };

            // Setup viewport.
            View = new Viewport2D(this);
            View.SpriteSorting = SpriteSortMode.FrontToBack;
            View.Camera.SpatialProperties.Size = new Vector2(100, 75);
            View.Depth = 0.5f;
            //View.Camera.CentreCamera(TileClass.SpatialProperties.Position - new Vector2(0,-72));

        }

        #endregion


        #region Update

        protected override void DoUpdate(GameTime Time)
        {
            if (LoadWorldDialog)
            {
                foreach (MenuItem_Text a in EditorLabels)
                    if (a.IsHighlighted)
                        for (int i = 0; i < EditorLabels.Count; i++)
                            if (a.TextActor.Text == EditorLabels[i].TextActor.Text)
                                Increment = i;

                if (EnterPressed || ClickPressed)
                {
                    foreach (MenuItem_Text m in EditorLabels)
                        m.Dispose();
                    LoadWorldDialog = false;

                    TileClass = new TileClass(this);
                    TileClass.SpatialProperties.Position = new Vector2(50f, -15);
                    TileClass.SpatialProperties.Size = new Vector2(1, 1);
                    TileClass.FileName = EditorLabels[Increment].TextActor.Text;
                    TileClass.IntiateLoadingProcedure = true;

                    CameraAmount = new Vector2(TileClass.TileWidth / (View.RenderTarget.Width / View.Camera.SpatialProperties.Size.X),
                           TileClass.TileHeight / (View.RenderTarget.Height / View.Camera.SpatialProperties.Size.Y));

                    EnterPressed = false;
                    ClickPressed = false;
                }
            }
            base.DoUpdate(Time);
        }
        #endregion

        private void ItemHighlighted(Object Item, EventArgs Args)
        {
            MenuItem_Text Text = Item as MenuItem_Text;
            Text.Actor.ColourOverlay = Color.Green;
            Text.TextActor.NaturalFontScaling = Vector2.One / 7f;
        }

        private void ItemLeft(Object Item, EventArgs Args)
        {
            MenuItem_Text Text = Item as MenuItem_Text;
            Text.Actor.ColourOverlay = Color.White;
            Text.TextActor.NaturalFontScaling = Vector2.One / 9f;
        }

        private void MakeItem(ref MenuItem_Text Item, String Text)
        {
            Item = new MenuItem_Text(this, Text, "Font/Basic");
            Item.SpatialProperties.Position = new Vector2(51.2f, VerticalPosition);
            Item.TextActor.NaturalFontScaling = Vector2.One / 9f;
            Item.TextActor.ColourOverlay = Color.White;
            Item.ItemHighlighted += ItemHighlighted;
            Item.ItemLeft += ItemLeft;
            VerticalPosition += VerticalOffset;
        }

        private void SetUpLoadScreen()
        {
            if (TileClass != null)
                TileClass.Dispose();

            if (EditorLabels.Count > 0)
                EditorLabels.Clear();

            LoadWorldDialog = true;
            DirectoryInfo Dir = new DirectoryInfo(Game.Content.RootDirectory);
            string[] dirPaths;
            if (!Dir.Exists)
                throw new DirectoryNotFoundException();

            FileInfo[] Files = Dir.GetFiles("*.xml");
            dirPaths = new string[Files.Length];
            int count = 0;
            foreach (FileInfo F in Files)
            {
                dirPaths[count] = Path.GetFileNameWithoutExtension(F.Name);
                EditorLabels.Add(new MenuItem_Text(this, " ", "Font/Basic"));
                count++;
            }

            MakeTextLists(ref EditorLabels, new Vector2(40, 25), dirPaths, true, Color.White, Color.Green);
            foreach (MenuItem_Text m in EditorLabels)
                m.ItemClicked += delegate(Object Itema, EventArgs Argsa) { ClickPressed = true; };
        }

        private void MakeTextLists(ref List<MenuItem_Text> List, Vector2 BeginPosi, string[] strings, bool Highlightable, Color off, Color On)
        {
            int incrementer = 0;
            foreach (MenuItem_Text Item in List)
            {
                Item.SpatialProperties.Position = new Vector2(BeginPosi.X, BeginPosi.Y + (incrementer * 5));
                Item.TextActor.NaturalFontScaling = Vector2.One / 9f;
                Item.TextActor.ColourOverlay = off;
                if (Highlightable)
                {
                    if (On == Color.Green)
                        Item.ItemHighlighted += ItemHighlighted;
                    else Item.ItemHighlighted += ItemHighlighted;
                    Item.ItemLeft += ItemLeft;
                }
                VerticalPosition += VerticalOffset;
                Item.Actor.Depth = 0.7f;
                if (incrementer >= strings.Length || incrementer < 0)
                    Item.TextActor.Text = " ";
                else
                {
                    Item.TextActor.Text = strings[incrementer];
                    if (Item.TextActor.Text == "OK" || Item.TextActor.Text == "Done" || Item.TextActor.Text == "Cancel")
                        Item.TextActor.ColourOverlay = Color.Gold;
                }
                incrementer++;
            }
        }
    }
}
